<?php
/**
 * Created by PhpStorm.
 * User: yangos
 * Date: 18-6-18
 * Time: 上午4:03
 */

namespace vola;


class Config {

    public $config;

    public function __construct()
    {
    }

    public function set($name, $value = null) {
        if (is_array($name)) {
            $this->config = array_merge($this->config, $name);
        } else {
            if (is_array($value)) {
                $this->config[$name] = $value;
            } else {
                if (strpos($name, '.') === false) {
                    $this->config[$name] = $this->convertConfig($value);
                } else {
                    $data = explode('.', $name);
                    $name = array_shift($data);

                    if (isset($this->config[$name])) {
                        $temp = &$this->config[$name];

                        foreach ($data as $v) {
                            if (isset($temp[$v])) {
                                $temp = &$temp[$v];
                            } else {
                                unset($temp);
                                $temp = '';
                                break;
                            }
                        }

                        if (!empty($temp)) {
                            $temp = $value;
                            unset($temp);
                        }
                    }
                }
            }

        }
    }

    public function get($name) {
        if (strpos($name, '.')) {
            $name = explode('.', $name);
            $config = array_shift($name);
            if (!isset($this->config[$config])) {
                return null;
            }
            $config = $this->config[$config];

            foreach ($name as $value) {
                if (!isset($config[$value])) {
                    return null;
                }
                $config = $config[$value];
            }
            return $config;
        }
        if (!isset($this->config[$name])) {
            return null;
        }
        return $this->config[$name];
    }

    public function has($name) {
        if (strpos($name, '.')) {
            $name = explode('.', $name);
            $config = array_shift($name);
            if (!isset($this->config[$config])) {
                return false;
            }
            $config = $this->config[$config];
            foreach ($name as $value) {
                if (!isset($config[$value])) {
                    return false;
                }
                $config = $config[$value];
            }
            return true;
        }
        return isset($this->config[$name]);
    }


    /**
     * @param string $name
     * @return bool|null
     */
    public function del($name) {
        if (strpos($name, '.')) {
            $name = explode('.', $name);
            $config = array_shift($name);
            $need = array_pop($name);
            if (!isset($this->config[$config])) {
                return null;
            }
            $config = &$this->config[$config];
            if (!empty($name)) {
                foreach ($name as $value) {
                    if (!isset($config[$value])) {
                        return false;
                    }
                    $config = &$config[$value];
                }
            }
            unset($config[$need]);
            unset($config);
        } else {
            if (isset($this->config[$name])) {
                unset($this->config[$name]);
            }
        }
    }


    public function setArray(array $array) {
        foreach ($array as $key => $value) {
            $this->set($key, $value);
        }
    }

    private function convertConfig($config = '') {
        if (strpos($config, '{') !== false) {
            return preg_replace_callback('/\{(.*?)\}/i', function ($match) {
                $tpl = trim($match[1]);

                if (strpos($tpl, '.')) {
                    $tpl = explode('.', $tpl);
                    $value = array_shift($tpl);
                    $temp = [];
                    if (isset($this->config[$value])) {
                        $temp = $this->config[$value];
                    } else {
                        return $match[0];
                    }
                    foreach ($tpl as $value) {
                        if (isset($temp[$value])) {
                            $temp = $temp[$value];
                        } else {
                            return $match[0];
                        }
                    }
                    return $temp;
                } else {
                    if (isset($this->config[$tpl])) {
                        return $this->config[$tpl];
                    } else {
                        return $match[0];
                    }
                }
            }, $config);
        }
        return $config;
    }

}